#pragma once

#include "rclcpp/rclcpp.hpp"
#include <cmath>
#include <memory>
#include <agv_msgs/msg/agv_event_status.hpp>
#include <agv_srvs/srv/control_voice.hpp>
#include <agv_msgs/msg/out_puts_new.hpp>
#include <agv_srvs/srv/outputs_new.hpp>
#include <agv_msgs/msg/control_voice.hpp>
#include "toolKit.h"

// 控制输出点名字列表....
#define DO_NAME_LAMP_GREEN "greenLight"   // 绿灯输出key名字
#define DO_NAME_LAMP_YELLOW "yellowLight" // 黄灯输出key名字
#define DO_NAME_LAMP_RED "redLight"       // 红灯输出key名字

#define DO_NAME_SPEAKER_1 "speaker_1"       // 喇叭输出key名字
#define DO_NAME_SPEAKER_2 "speaker_2"       // 喇叭输出key名字
#define DO_NAME_SPEAKER_3 "speaker_3"       // 喇叭输出key名字
#define DO_NAME_SPEAKER_4 "speaker_4"       // 喇叭输出key名字

#define DO_NAME_LAMP_HOST "netConnectLight"       // 调度连接输出key名字
#define DO_NAME_LAMP_LOWBAT "lowBatteryLight"     // 低电量输出key名字
#define DO_NAME_LAMP_LOCATION "locationLight"     // 定位输出key名字
#define DO_NAME_LAMP_EMGECY "emgLight"            // 急停指示灯名字
#define DO_NAME_LAMP_RESET "resetBtnLight"        // 复位按钮输出key名字

#define DO_NAME_OUTLIEN_LAMP "outlineLamp"      // 叉车探照灯名字
#define DO_NAME_WINDFAN "windFan"               // 叉车风扇
#define DO_NAME_LEFTTURN "leftTurnLight"        // 叉车左转向灯
#define DO_NAME_RIGHTTURN "rightTurnLight"      // 叉右转向灯
#define DO_NAME_THIRDLIFT "thirdLift"            // 第三方工装急停


using AUDIO_TYPE = std::pair<int, int>;
class OutputInterface
{
public:
  // first:#（0~100对应的音频文件，0-关闭声音）
  // second:# 音量大小（0~28）

  using DEVICE_TYPE = std::pair<std::string, int>;
  // 名字：索引
  using MapOutputType = std::map<std::string, int>;
  using MapIterType = MapOutputType::iterator;

    // 定义输出控制IO点类型
  // 参数： first:io名字 second:控制输出的电平
  using OUTPUT_IO_TYPE = agv_msgs::msg::PairTypeInt;
  // IO控制输出组
  using IO_GROUP = std::vector<OUTPUT_IO_TYPE>;

  OutputInterface():canSpeaker_(true)
  { 
  }

 ~OutputInterface(){};

private:
  std::shared_ptr<rclcpp::Node> node_;
  bool  canSpeaker_,
        useIOService_,
        useLouderService_;
  rclcpp::Client<agv_srvs::srv::ControlVoice>::SharedPtr canSpeakerClient_;
  rclcpp::Client<agv_srvs::srv::OutputsNew>::SharedPtr output_map_client_;
  rclcpp::Publisher<agv_msgs::msg::OutPutsNew>::SharedPtr io_pub_;
  rclcpp::Publisher<agv_msgs::msg::ControlVoice>::SharedPtr louder_pub_;
  IO_GROUP  outPuts_;
  MapOutputType outPuts_last_;
public:
  bool callOutputSrv(rclcpp::Client<agv_srvs::srv::OutputsNew>::SharedPtr client, const IO_GROUP &group);
  bool haveParam(std::string outStr, IO_GROUP &group);
  void setOnePoint(bool level,  std::string key, bool push = false);
  void setSeveralPoint(bool level, IO_GROUP &group);
  void clearOutputs(void);
  bool outputsPub(void);
  bool callCANAudioSrv(AUDIO_TYPE audio);
  void sound(AUDIO_TYPE audio);
  void init(const std::shared_ptr<rclcpp::Node>node, const bool enable_speak = true);
};
